package com.spring.boot.core.utils;

import java.util.ArrayList;

public class HashUtils {

	/**
	 * 最好
	 * 
	 * @param str
	 * @return
	 */
	public static final int hash(String str) {
		// 取31等于str.hashCode();
		int seed = 131; // 31 131 1313 13131 131313 etc..
		int hash = 0;
		char val[] = str.toCharArray();
		if (val.length > 0) {
			int size = val.length;
			for (int i = 0; i < size; i++) {
				hash = hash * seed + val[i];
			}
		}
		// &0x7FFFFFFF反正为负数, 0x7FFFFFFF=2147483647
		return (hash & 0x7FFFFFFF);
	}

	/**
	 * 可以
	 * 
	 * @param str
	 * @return
	 */
	final static int hashByHashCode(String str) {
		return str.hashCode() & 0x7FFFFFFF;
	}

	/**
	 * 可以
	 * 
	 * @param str
	 * @return
	 */
	final static int hashByHashMap(String str) {
		int code = str.hashCode();
		return (code ^ (code >>> 16)) & 0x7FFFFFFF;

	}

	/**
	 * 有缺陷
	 * 
	 * @param strUser
	 * @return
	 * @throws Exception
	 */
	static final int userHash(String strUser) throws Exception {
		ArrayList<String> strHash = new ArrayList<String>(16);
		String signal = MD5Utils.encryptToHex(strUser);
		for (int i = 0; i < 32; i = i + 2) {
			String sub = signal.substring(i, i + 1);
			strHash.add(sub);
		}
		int[] aryIntHash = new int[4];
		int Int4C = 0;

		for (int j = 0; j < 4; j++) {
			for (int i = 0; i < 4; i++) {
				Int4C |= ascii(strHash.get(i + j * 4)) & 0xff;
				if (i < 3)
					Int4C = Int4C << 8;
			}
			aryIntHash[j] = Int4C;
			Int4C = 0;
		}

		int xHash = aryIntHash[0] ^ aryIntHash[1] | aryIntHash[2] ^ aryIntHash[3];

		return (xHash / 387) % 4;
	}

	static int ascii(String str) {
		char c = str.charAt(0);
		return Integer.valueOf(c);
	}

	static String stringToAscii(String value) {
		StringBuffer sbu = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			if (i != chars.length - 1) {
				sbu.append((int) chars[i]).append(",");
			} else {
				sbu.append((int) chars[i]);
			}
		}
		return sbu.toString();
	}

	public static void main(String[] args) throws Exception {
		int t0 = 0;
		int t1 = 0;
		int t2 = 0;
		int t3 = 0;
		for (int i = 0; i < 10000000; i++) {
			String str = Utils.randomUID();
			int hash = userHash(str);
			if (hash == 0) {
				t0++;
			} else if (hash == 1) {
				t1++;
			} else if (hash == 2) {
				t2++;
			} else if (hash == 3) {
				t3++;
			}
		}
		System.out.println(t0 + "," + t1 + "," + t2 + "," + t3);

		t0 = 0;
		t1 = 0;
		t2 = 0;
		t3 = 0;
		for (int i = 0; i < 10000000; i++) {
			String str = Utils.randomUID();
			int hash = hash(str) % 4;
			if (hash == 0) {
				t0++;
			} else if (hash == 1) {
				t1++;
			} else if (hash == 2) {
				t2++;
			} else if (hash == 3) {
				t3++;
			}
		}
		System.out.println(t0 + "," + t1 + "," + t2 + "," + t3);

		t0 = 0;
		t1 = 0;
		t2 = 0;
		t3 = 0;
		for (int i = 0; i < 10000000; i++) {
			String str = Utils.randomUID();
			int hash = hashByHashCode(str) % 4;
			if (hash == 0) {
				t0++;
			} else if (hash == 1) {
				t1++;
			} else if (hash == 2) {
				t2++;
			} else if (hash == 3) {
				t3++;
			}
		}
		System.out.println(t0 + "," + t1 + "," + t2 + "," + t3);

		t0 = 0;
		t1 = 0;
		t2 = 0;
		t3 = 0;
		for (int i = 0; i < 10000000; i++) {
			String str = Utils.randomUID();
			int hash = hashByHashMap(str) % 4;
			if (hash == 0) {
				t0++;
			} else if (hash == 1) {
				t1++;
			} else if (hash == 2) {
				t2++;
			} else if (hash == 3) {
				t3++;
			}
		}
		System.out.println(t0 + "," + t1 + "," + t2 + "," + t3);

	}

}
